package Servlet;

import Model.UsuarioBean;
import Model.ArvoreBean;
import Model.Condicional;
import Model.Consulta;
import ConnectionDB.SorocabaDAO;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletOutputStream;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.ResultSet;
import java.sql.SQLException;

public class Usuario extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setCharacterEncoding("UTF8");
        request.setCharacterEncoding("UTF8");

        String acao = request.getParameter("acao").toString();

        if (acao.contentEquals("login")) {
            logarUsuario(request, response);
        } else if (acao.contentEquals("cadastrar")) {
            cadastrarUsuario(request, response);
        } else if (acao.contentEquals("editar")) {
            editarUsuario(request, response);
        } else if (acao.contentEquals("logout")) {
            logoutUsuario(request, response);
        } else if (acao.contentEquals("prepararConsulta")) {
            prepararConsulta(request, response);
        } else if (acao.contentEquals("consultar")) {
            consultarBaseDeDados(request, response);
        } else if (acao.contentEquals("mudarPagina")) {
            mudarPagina(request, response);
        } else if (acao.contentEquals("mudarPaginaExplorar")) {
            mudarPaginaExplorar(request, response);
        } else if (acao.contentEquals("exportarResultados")) {
            exportarResultados(request, response);
        } else if (acao.contentEquals("prepararExplorar")) {
            prepararExplorar(request, response);
        } else if (acao.contentEquals("selecionarConsulta")) {
            selecionarConsulta(request, response);
        } else if (acao.contentEquals("explorarCenso")) {
            explorarCenso(request, response);
        } else if (acao.contentEquals("explorarAmostragem")) {
            explorarAmostragem(request, response);
        }
    }

    protected void logarUsuario(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        UsuarioBean usuario = new UsuarioBean();
        String email, senha, infohtml = "";

        email = request.getParameter("email").toString();
        senha = request.getParameter("senha").toString();

        SorocabaDAO sorocaba = new SorocabaDAO();

        usuario = sorocaba.logarUsuario(email, senha);

        if (usuario != null) {
            sorocaba = new SorocabaDAO();
            infohtml = sorocaba.infoBanco();

            HttpSession sessao = request.getSession();
            sessao.setAttribute("usuario", usuario);
            sessao.setAttribute("infohtml", infohtml);
            response.sendRedirect("index.jsp");
        } else {
            RequestDispatcher rd = null;
            rd = request.getRequestDispatcher("/erro.jsp");
            rd.forward(request, response);
        }
    }

    protected void cadastrarUsuario(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        UsuarioBean usuario = new UsuarioBean();
        int sucesso = 0;
        String infohtml = "";

        usuario.setNome(request.getParameter("nome").toString());
        usuario.setCidade(request.getParameter("cidade").toString());
        usuario.setEstado(request.getParameter("estado").toString());
        usuario.setEmail(request.getParameter("email").toString());
        usuario.setSenha(request.getParameter("senha1").toString());

        SorocabaDAO sorocaba = new SorocabaDAO();

        sucesso = sorocaba.cadastrarUsuario(usuario);

        if (sucesso == 1) {
            sorocaba = new SorocabaDAO();

            usuario = sorocaba.logarUsuario(usuario.getEmail(), usuario.getSenha());
            sorocaba = new SorocabaDAO();
            infohtml = sorocaba.infoBanco();

            HttpSession sessao = request.getSession();
            sessao.removeAttribute("usuario");
            sessao.setAttribute("usuario", usuario);
            sessao.setAttribute("infohtml", infohtml);
            response.sendRedirect("cadastrar_sucesso.jsp");
        } else {
            RequestDispatcher rd = null;
            rd = request.getRequestDispatcher("/cadastrar_erro.jsp");
            rd.forward(request, response);
        }
    }

    protected void editarUsuario(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession sessao = request.getSession(false);
        UsuarioBean novoUsuario = new UsuarioBean();
        UsuarioBean usuario = new UsuarioBean();
        String email, senha;

        usuario = (UsuarioBean) sessao.getAttribute("usuario");

        novoUsuario.setNome(request.getParameter("nome").toString());
        novoUsuario.setEmail(usuario.getEmail());
        novoUsuario.setCidade(request.getParameter("cidade").toString());
        novoUsuario.setEstado(request.getParameter("estado").toString());
        novoUsuario.setSenha(request.getParameter("senha1").toString());

        email = usuario.getEmail();
        senha = request.getParameter("senha_antiga").toString();

        SorocabaDAO sorocaba = new SorocabaDAO();

        usuario = sorocaba.logarUsuario(email, senha);

        if (usuario != null) {
            sorocaba = new SorocabaDAO();
            novoUsuario = sorocaba.editarUsuario(novoUsuario);

            sessao.removeAttribute("usuario");
            sessao.setAttribute("usuario", novoUsuario);
            response.sendRedirect("editar_sucesso.jsp");
        } else {
            RequestDispatcher rd = null;
            rd = request.getRequestDispatcher("/editar_erro.jsp");
            rd.forward(request, response);
        }
    }

    protected void logoutUsuario(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession sessao = request.getSession(false);

        if (sessao != null) {
            sessao.invalidate();
        }
        RequestDispatcher rd = null;
        rd = request.getRequestDispatcher("/logout.jsp");
        rd.forward(request, response);
    }

    protected void mudarPagina(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession sessao = request.getSession(false);
        int paginaInicial = Integer.parseInt(request.getParameter("paginaInicial").toString());

        sessao.removeAttribute("paginaInicial");
        sessao.setAttribute("paginaInicial", paginaInicial);

        RequestDispatcher rd = null;
        rd = request.getRequestDispatcher("/resultado.jsp");
        rd.forward(request, response);
    }
    
    protected void mudarPaginaExplorar(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession sessao = request.getSession(false);
        int paginaInicial = Integer.parseInt(request.getParameter("paginaInicial").toString());

        sessao.removeAttribute("paginaInicial");
        sessao.setAttribute("paginaInicial", paginaInicial);

        RequestDispatcher rd = null;
        rd = request.getRequestDispatcher("/resultado_explorar.jsp");
        rd.forward(request, response);
    }

    protected void exportarResultados(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession sessao = request.getSession(false);
        ServletOutputStream out = null;
        String buffer = "";
        ResultSet resultado = (ResultSet) sessao.getAttribute("resultado");

        try {
            if (resultado != null) {
                int numeroColunas = resultado.getMetaData().getColumnCount();
                out = response.getOutputStream();

                response.setContentType("application/octet-stream");
                response.addHeader("Content-Disposition", "attachment; filename=\" " + "resultados_consulta.csv" + "\";");


                out.print("No;");
                for (int i = 1; i <= numeroColunas; i++) {
                    out.print(resultado.getMetaData().getColumnLabel(i) + ";");
                }
                out.print("\n");

                int contadorResultados = 1;
                resultado.first();
                while (resultado.next()) {
                    out.print(contadorResultados + ";");
                    contadorResultados++;
                    for (int i = 1; i <= numeroColunas; i++) {
                        out.print(resultado.getString(i) + ";");
                    }
                    out.print("\n");
                }

                out.flush();
                out.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        RequestDispatcher rd = null;
        rd = request.getRequestDispatcher("/resultado.jsp");
        rd.forward(request, response);
    }
    
    protected void prepararConsulta(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession sessao = request.getSession(false);
        List<String> listaBairros, listaRuas, listaEspecies;
        List<Consulta> listaConsultas = null;

        SorocabaDAO sorocaba = new SorocabaDAO();

        listaConsultas = sorocaba.listarConsultas();
        sorocaba.closeConnection();

        sessao.setAttribute("listaConsultas", listaConsultas);

        RequestDispatcher rd = null;
        rd = request.getRequestDispatcher("/preparar_consulta.jsp");
        rd.forward(request, response);
    }

    protected void selecionarConsulta(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession sessao = request.getSession(false);
        int indexConsulta = Integer.parseInt(request.getParameter("indexConsulta").toString());

        sessao.setAttribute("indexConsulta", indexConsulta);

        RequestDispatcher rd = null;
        rd = request.getRequestDispatcher("/formulario_consulta.jsp");
        rd.forward(request, response);
    }

    protected void consultarBaseDeDados(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession sessao = request.getSession(false);
        int indexConsulta = (Integer) sessao.getAttribute("indexConsulta");
        List<Consulta> listaConsultas = (List<Consulta>) sessao.getAttribute("listaConsultas");
        String sql = listaConsultas.get(indexConsulta).getPreScript();
        String[] listaParametros;
        ResultSet resultado;
        int paginaInicial = 0;
        boolean parametroValido = false;

        int indexCondicao = 0, indexParametro = 0;
        String parametro = "";
        String condicaoAtual = "";
        String condicaoOriginal = "";


        while (indexCondicao < listaConsultas.get(indexConsulta).getListaCondicional().size()) {

            parametro = request.getParameter(listaConsultas.get(indexConsulta).getListaCondicional().get(indexCondicao).getTagHtml()).toString();
            listaParametros = parametro.split(";");
            condicaoOriginal = listaConsultas.get(indexConsulta).getListaCondicional().get(indexCondicao).getCondicao();

            indexParametro = 0;

            parametroValido = false;
            if (!(listaParametros[indexParametro].isEmpty())) {
                parametroValido = true;
                sql += "(";
                while (indexParametro < listaParametros.length) {
                    if (!(listaParametros[indexParametro].isEmpty())) {
                        if (condicaoOriginal.contains("ILIKE")) {
                            condicaoAtual = condicaoOriginal.replaceAll("@", "'%" + listaParametros[indexParametro] + "%'");
                        } else {
                            condicaoAtual = condicaoOriginal.replaceAll("@", "'" + listaParametros[indexParametro] + "'");
                        }

                        sql += condicaoAtual;

                        indexParametro++;

                        if (indexParametro < listaParametros.length) {
                            sql += " OR ";
                        }
                    } else {
                        indexParametro++;
                    }
                }
                sql += ")";
            } else {
                parametroValido = false;
            }


            indexCondicao++;
            if (indexCondicao <= listaConsultas.get(indexConsulta).getListaCondicional().size()) {
                if (parametroValido) {
                    sql += " AND ";
                }
            }
        }

        sql += listaConsultas.get(indexConsulta).getPosScript() + ";";
        sql = sql.replaceAll("WHERE AND ", "WHERE ");

        SorocabaDAO sorocaba = new SorocabaDAO();

        resultado = sorocaba.executarConsulta(sql);
        sessao.setAttribute("resultado", resultado);
        sessao.setAttribute("paginaInicial", paginaInicial);


        RequestDispatcher rd = null;
        rd = request.getRequestDispatcher("/resultado.jsp");
        rd.forward(request, response);
    }

    protected void prepararExplorar(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession sessao = request.getSession(false);

        if (sessao.getAttribute("selectBairro") == null) {
            List<String> listaBairro,
                    listaRua,
                    listaEspecie,
                    listaGenero,
                    listaNomePopular;

            String selectBairro = "",
                    selectRua = "",
                    selectEspecie = "",
                    selectGenero = "",
                    selectNomePopular = "";

            SorocabaDAO sorocaba = new SorocabaDAO();

            listaBairro = sorocaba.listarBairro();
            listaRua = sorocaba.listarRua();
            listaEspecie = sorocaba.listarEspecie();
            listaGenero = sorocaba.listarGenero();
            listaNomePopular = sorocaba.listarNomePopular();

            sorocaba.closeConnection();

            selectBairro = "<select id='bairro' name='bairro' ><option value='NULL' selected='selected' >Qualquer Bairro</option>";
            selectRua = "<select id='rua' name='rua' ><option value='NULL' selected='selected' >Qualquer Rua</option>";
            selectEspecie = "<select id='especie' name='especie' ><option value='NULL' selected='selected' >Qualquer Espécie</option>";
            selectGenero = "<select id='genero' name='genero' ><option value='NULL' selected='selected' >Qualquer Gênero</option>";
            selectNomePopular = "<select id='nome_popular' name='nome_popular' ><option value='NULL' selected='selected' >Qualquer Nome</option>";

            for (int i = 0; i < listaBairro.size(); i++) {
                selectBairro += "<option value=\"\'"
                        + listaBairro.get(i)
                        + "\'\" >"
                        + listaBairro.get(i)
                        + "</option>";
            }

            for (int i = 0; i < listaRua.size(); i++) {
                selectRua += "<option value=\"\'"
                        + listaRua.get(i)
                        + "\'\" >"
                        + listaRua.get(i)
                        + "</option>";
            }

            for (int i = 0; i < listaEspecie.size(); i++) {
                selectEspecie += "<option value=\"\'"
                        + listaEspecie.get(i)
                        + "\'\" >"
                        + listaEspecie.get(i)
                        + "</option>";
            }

            for (int i = 0; i < listaGenero.size(); i++) {
                selectGenero += "<option value=\"\'"
                        + listaGenero.get(i)
                        + "\'\" >"
                        + listaGenero.get(i)
                        + "</option>";
            }

            for (int i = 0; i < listaNomePopular.size(); i++) {
                selectNomePopular += "<option value=\"\'"
                        + listaNomePopular.get(i)
                        + "\'\" >"
                        + listaNomePopular.get(i)
                        + "</option>";
            }

            selectBairro += "</select>";
            selectRua += "</select>";
            selectEspecie += "</select>";
            selectGenero += "</select>";
            selectNomePopular += "</select>";

            sessao.setAttribute("selectRua", selectRua);
            sessao.setAttribute("selectBairro", selectBairro);
            sessao.setAttribute("selectEspecie", selectEspecie);
            sessao.setAttribute("selectGenero", selectGenero);
            sessao.setAttribute("selectNomePopular", selectNomePopular);
        }

        RequestDispatcher rd = null;
        rd = request.getRequestDispatcher("/explorar_censo.jsp");
        rd.forward(request, response);
    }

    protected void explorarCenso(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession sessao = request.getSession(false);
        ResultSet resultado;
        String rua,
                bairro,
                especie,
                nomePopular,
                genero,
                origem,
                alturaTotal,
                alturaBifurcacao,
                raioCopaMinimo,
                raioCopaMaximo,
                areaCopaMinimo,
                areaCopaMaximo,
                dano,
                tipoPlantio,
                situacao,
                matriz;

        rua = request.getParameter("rua").toString();
        bairro = request.getParameter("bairro").toString();
        especie = request.getParameter("especie").toString();
        nomePopular = request.getParameter("nome_popular").toString();
        genero = request.getParameter("genero").toString();
        origem = request.getParameter("origem").toString();
        alturaTotal = request.getParameter("altura_total").toString();
        alturaBifurcacao = request.getParameter("altura_bifurcacao").toString();
        raioCopaMinimo = request.getParameter("raio_minimo").toString();
        raioCopaMaximo = request.getParameter("raio_maximo").toString();
        areaCopaMinimo = request.getParameter("area_minimo").toString();
        areaCopaMaximo = request.getParameter("area_maximo").toString();
        dano = request.getParameter("dano").toString();
        tipoPlantio = request.getParameter("tipo_plantio").toString();
        situacao = request.getParameter("situacao").toString();
        matriz = request.getParameter("matriz").toString();
        
        raioCopaMinimo = "'" + raioCopaMinimo.replace(',', '.') + "'";
        raioCopaMaximo = "'" + raioCopaMaximo.replace(',', '.') + "'";
        areaCopaMinimo = "'" + areaCopaMinimo.replace(',', '.') + "'";
        areaCopaMaximo = "'" + areaCopaMaximo.replace(',', '.') + "'";
                
        if(raioCopaMinimo.contentEquals("''")){
            raioCopaMinimo = "NULL";
        }
        if(raioCopaMaximo.contentEquals("''")){
            raioCopaMaximo = "NULL";
        }
        if(areaCopaMinimo.contentEquals("''")){
            areaCopaMinimo = "NULL";
        }
        if(areaCopaMaximo.contentEquals("''")){
            areaCopaMaximo = "NULL";
        }

        SorocabaDAO sorocaba = new SorocabaDAO();

        resultado = sorocaba.explorarCenso(rua, bairro, especie, nomePopular, genero, origem, alturaTotal, alturaBifurcacao, raioCopaMinimo, raioCopaMaximo, areaCopaMinimo, areaCopaMaximo, dano, tipoPlantio, situacao, matriz);
        int paginaInicial = 0;
        
        sessao.setAttribute("resultadoExplorar", resultado);
        sessao.setAttribute("paginaInicial", paginaInicial);
        RequestDispatcher rd = null;
        rd = request.getRequestDispatcher("/resultado_explorar.jsp");
        rd.forward(request, response);
    }

    protected void explorarAmostragem(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    }
}
